package com.unbox.common.configuration.mybatisplus.seata;

import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.HikariPoolMXBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

/**
 * seata dataSource 配置
 * @author 王振宇
 */
@EnableConfigurationProperties({DataSourceProperties.class})
public class UnBoxSeataAutoConfiguration {
    @Value("${spring.datasource.hikari.minimum-idle}")
    Integer minimumIdle;
    @Value("${spring.datasource.hikari.maximum-pool-size}")
    Integer maximumPoolSize;
    @Value("${spring.datasource.hikari.auto-commit}")
    Boolean autoCommit;
    @Value("${spring.datasource.hikari.idle-timeout}")
    Integer idleTimeout;
    @Value("${spring.datasource.hikari.pool-name}")
    String poolName;
    @Value("${spring.datasource.hikari.max-lifetime}")
    Integer maxLifetime;
    @Value("${spring.datasource.hikari.connection-timeout}")
    Integer connectionTimeout;
    @Value("${spring.datasource.hikari.connection-test-query}")
    String connectionTestQuery;
    @Value("${mybatis-plus.mapper-locations}")
    String mapperLocations;
    @Value("${mybatis-plus.type-aliases-package}")
    String typeAliasesPackage;

    @Autowired
    DataSourceProperties dataSourceProperties;

    /**
     * 初始化dataSource
     * @return
     */
    @Bean
    public DataSource getDataSource() {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(dataSourceProperties.getDriverClassName());
        hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
        hikariConfig.setUsername(dataSourceProperties.getUsername());
        hikariConfig.setPassword(dataSourceProperties.getPassword());
        hikariConfig.setMinimumIdle(minimumIdle);
        hikariConfig.setMaximumPoolSize(maximumPoolSize);
        hikariConfig.setIdleTimeout(idleTimeout);
        hikariConfig.setAutoCommit(autoCommit);
        hikariConfig.setPoolName(poolName);
        hikariConfig.setMaxLifetime(maxLifetime);
        hikariConfig.setConnectionTimeout(connectionTimeout);
        hikariConfig.setConnectionTestQuery(connectionTestQuery);
        return new HikariDataSource(hikariConfig);
    }

    /**
     * 初始化数据库session 配置mybatis plus分页插件
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        List sqlParselist = new ArrayList();
        sqlParselist.add(new BlockAttackSqlParser());
        paginationInterceptor.setSqlParserList(sqlParselist);
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        mybatisSqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources(mapperLocations));
        mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
        mybatisSqlSessionFactoryBean.setPlugins(new Interceptor[] {
                paginationInterceptor,
                new OptimisticLockerInterceptor()
        });
        mybatisSqlSessionFactoryBean.setDataSource(dataSource);
        return mybatisSqlSessionFactoryBean.getObject();
    }
}
